@cc_on

// Constants for file system object.
@set @ForReading = 1
@set @ForWriting = 2
@set @ForAppending = 3

// The global file system object.
var file_system = new ActiveXObject( 'Scripting.FileSystemObject' );

/*
 * File class that uses the FileSystemObject.
 */

// Attempts to open the specified filename.  Returns true if successful
// false otherwise.
function File_open(filename, mode) {
  var i;
  var open_mode = ForReading;

  // Translate the open mode.
  if (!isUndefined(mode)) {
    for (i = 0; i < mode.length; i++) {
      var mode_character = mode.charAt(i);
      switch (mode) {
      case 'r':
        open_mode = ForReading;
        break;
      case 'w':
        open_mode = ForWriting;
        break;
      case 'a':
        open_mode = ForAppending;
        break;
      default:
        return false;
      }
    }
  }

  // If the file is opened for reading or appending make sure it exists.
  switch (open_mode) {
  case ForReading:
  case ForAppending:
    if (!file_system.Exists(filename)) {
      return false;
    }
    break;
  default:
    break;
  }

  this.file = file_system.OpenTextFile(filename, open_mode, true);
  if (!this.isOpen()) {
    return false;
  }
  this.filename = filename;
  this.open_mode = open_mode;
  return true;
}

// Determine whether the file is open.
function File_isOpen() {
  return !isUndefined(this.file);
}

// Close the file.
function File_close() {
  // Only close if the file is open.
  if (this.isOpen()) {
    this.file.Close();
    this.file = undefined;
    this.filename = undefined;
    this.open_mode = undefined;
  }
}

// Ensure the file is opened.
function File__checkOpen() {
  if (!this.isOpen()) {
    throw 'File not open';
  }
}

// Ensure the file is opened for reading.
function File__checkOpenReadOnly() {
  _checkOpen();
  if (this.open_mode != ForReading) {
    throw this.filename + ' not opened for reading';
  }
}

// Ensure the file is opened for writing.
function File__checkOpenWriteOnly() {
  _checkOpen();
  if (this.open_mode == ForReading) {
    throw this.filename + ' not opened for writing';
  }
}

// Read the file, returning the string read from the file.
function File_read(read_size) {
  _checkOpenReadOnly();
  if (isUndefined(read_size)) {
    return this.file.ReadAll();
  }
  return this.file.Read(read_size);
}

// Read a line from the file.
function File_readLine() {
  _checkOpenReadOnly();
  return this.file.ReadLine();
}

// Skip a line in the file.
function File_skipLine() {
  _checkOpenReadOnly();
  this.file.SkipLine();
}

// Seek within the file relative to the current file position.
function File_seek(offset) {
  _checkOpen();
  if (this.open_mode != ForAppending) {
    throw this.filename + ' is opened for appending';
  }
  this.file.Skip(offset);
}

// Write to the file.
function File_write(string) {
  _checkOpenWriteOnly();
  this.file.Write(string);
}

// Write a line to the file.
function File_writeLine(string) {
  _checkOpenWriteOnly();
  this.file.WriteLine(string);
}

// Write a number of newlines to the file.
function File_writeBlankLines(number_of_blank_lines) {
  _checkOpenWriteOnly();
  this.file.WriteBlankLines(number_of_blank_lines);
}


function File(filename, mode) {
  this.file = undefined;
  this.filename = undefined;
  this.open_mode = undefined;

  if (!isUndefined(filename)) {
    this.open(filename, mode);
  }
}

File.prototype.open = File_open;
File.prototype.isOpen = File_isOpen;
File.prototype.close = File_close;
File.prototype._checkOpen = File__checkOpen;
File.prototype._checkOpenReadOnly = File__checkOpenReadOnly;
File.prototype._checkOpenWriteOnly = File__checkOpenWriteOnly;
File.prototype.read = File_read;
File.prototype.readLine = File_readLine;
File.prototype.skipLine = File_skipLine;
File.prototype.seek = File_seek;
File.prototype.write = File_write;
File.prototype.writeLine = File_writeLine;
File.prototype.writeBlankLines = File_writeBlankLines;

